package com.yuchengtech.simpleServer.core.handler;

import java.io.IOException;
import java.net.Socket;

import sun.net.www.protocol.http.HttpURLConnection;

import com.wox.action.JsonData;
import com.wox.action.WoxAction;
import com.wox.config.Action;
import com.wox.config.ActionContext;
import com.wox.config.ActionMappings;
import com.wox.config.Forward;
import com.wox.config.GlobalForwards;
import com.wox.config.WoxConfig;
import com.wox.util.FillField;
import com.yuchengtech.simpleServer.core.Constant;
import com.yuchengtech.simpleServer.core.HttpRequest;
import com.yuchengtech.simpleServer.core.HttpResponse;

/**
 * This class handle the wox-action struts working.
 *@author David zhang
 *@since Tue 20 May 2011
 *@version 1.0
 */

public class ActionHandler implements Handler {

	private ActionMappings actionMappings;
	private GlobalForwards globalForwards;
	private boolean isOk = false;

	private ActionHandler()
	{
		if (WoxConfig.isInited()) {
			actionMappings = WoxConfig.getWoxConfig().getActionMappings();
			globalForwards = WoxConfig.getWoxConfig().getGlobalFrowardMap();
			isOk = true;
		}
	}
	
	private static final ActionHandler ACTION_HANDLER=new ActionHandler();
	
	public void doHandle(Socket connection, HttpRequest request,
			HttpResponse response) {
		if(!isOk)
			{
				response.setStatusCode(HttpURLConnection.HTTP_SERVER_ERROR);
				response.sendError(HttpURLConnection.HTTP_SERVER_ERROR, "Wox框架没有初始化");
				try {
					response.commitResponse();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		
		else
		{
			String actionId=request.getUri();
			// 将本次访问的request,response,servletContext装入WoxAction的本地线程变量中....
			WoxAction.local.set(new ActionContext(request, response));
			JsonData jsonData=new JsonData();
			request.setAttribute(Constant.JSONDATA_REQUEST,jsonData);
			try {
				actionExecute(connection,request, response,jsonData, actionId);
			} catch (Exception e) {
				e.printStackTrace();
				response.setStatusCode(HttpURLConnection.HTTP_SERVER_ERROR);
				response.sendError(HttpURLConnection.HTTP_SERVER_ERROR, e.toString());
				try {
					response.commitResponse();
				} catch (IOException e2) {
					//e.printStackTrace();
				}
			}
			

		}
	}


	private void actionExecute(Socket connection,HttpRequest request, HttpResponse response,JsonData jsonData,
			String actionId) throws Exception {
		Action action = actionMappings.getActionMap(actionId);
		if (action == null) {
			response.setErrorMsg("the id: ("+actionId+") action is not defined!");
			response.setStatusCode(HttpURLConnection.HTTP_NOT_FOUND);
			try {
				response.doResponse();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		
		WoxAction woxAction;
		try {
			woxAction = (WoxAction) Class.forName(action.getClassPath()).newInstance();
			// 自动封装Action中相应变量
			FillField.fill(woxAction, request.getParameterMap());
			/**
			 * 执行woxAction的excute方法，执行业务处理
			 */
			woxAction.setJsonData(jsonData);
			String forwardName = woxAction.excute();

			// 将action 存入相应的对象中
			if (action.getScope() != null) {
				if (action.getScope().equals("request")) {
					request.setAttribute(action.getAttribute(), woxAction);
				}
			}

			// 执行完毕后，得到在woxAction中的跳转对象
			Forward forward = action.getForward(forwardName);
			if (forward == null)
				forward = globalForwards.getForwardMap(forwardName);
			if (forward == null)
				forward = globalForwards.getForwardMap(WoxAction.JSONBACK);

			if (forward.isRedirect())//如果为重定向
				{
				response.setStatusCode(302);
				response.addHeader("Location",forward.getPath());
				response.commitResponse();
				}
			else
				{
				String forwardPath=forward.getPath();
				request.setNowUrl(forwardPath);

				 //case 1:如果是跳转下一个action
				  if("do".equals(request.getPostfix()))
					{
					 actionExecute(connection,request,response,jsonData,request.getUri());
					}
				 //case 2:如果是其他通过HttpHandler再次处理
				 else 
					 HttpHandler.handleProcess(connection, request, response);
				}
		} catch (Exception e) {
			e.printStackTrace();
			throw  e;
		}
	}

	
	
	 public static ActionHandler getSingleActionHandler()
	  {
		return ACTION_HANDLER;
	  }
}
